home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / tde.zip / TDE.DOC < prev    next >
Text File  |  1992-07-14  |  22KB  |  485 lines

  1.  
  2. FILENAME: TDE.DOC
  3. *****************
  4.                        Class TDataEntry v1.0 - 07/14/92
  5.                        --------------------------------
  6.  
  7.  ----------------------------------------------------------------------------
  8.  Author: Jeff Penrose * JDP Custom Software * (818) 344-7303 * CIS 71043,3727
  9.  ----------------------------------------------------------------------------
  10.  
  11.  A data entry class for Borland's Turbo Vision, derived from TInputLine.
  12.  
  13. TDataEntry's Features
  14. =====================
  15.   * non-scrollable input lines
  16.   * data entry masks consisting of writable/non-writable positions
  17.   * field validation/required checks
  18.   * field auto-exit
  19.   * field location by name and/or number
  20.   * user restoral of original field data (CTRL-R)
  21.   * queries: field changed/field valid either global or field-specific
  22.   * option to treat ENTER like TAB, up/down arrow inter-field movement,
  23.     validation immediately or at a later time (such as when saving)
  24.   * special derivatives of TInputLine/TCluster which inherit some of the
  25.     functionality of TDataEntry so field behavior is consistent
  26.  
  27. TDataEntry's Philosophy
  28. =======================
  29.   I needed a class which allowed me to keep tabs on what the user was entering,
  30.  control the presentation of data, and be able to quickly locate a field
  31.  without having to keep a bunch of field pointers hanging around.
  32.   I wanted strong validation capabilites, including checking for missing data.
  33.  I wanted to have certain types of data fields (such as states, zip codes,
  34.  phone numbers) to automatically exit when the user entered the last character,
  35.  without having to hit RETURN.
  36.   I wanted to be able to use the RETURN key for inter-field movement, as well
  37.  as the up/down arrow keys.
  38.   At the same time, I realized that MOST of the fields which I created would
  39.  be displayed in their entirety.  If a customer name field is used, I didn't
  40.  want it to be scrollable, since the user probably would want to see the
  41.  whole thing on screen anyway.
  42.   Finally, I wanted to be able to turn on/off the above-mentioned features; I
  43.  wanted flexibility.
  44.  
  45. Copyright Notice
  46. ================
  47.   As this material is ultimately derived from Borland source files, any of
  48.  their copyrights which MAY apply DO apply.
  49.   From the author's standpoint, you may use this material freely and,
  50.  hopefully, post any comments/corrections/enhancements to me at the above-
  51.  noted addresses.  I do ask that you not distribute this material except as
  52.  originally received, including all source/documentation files in their
  53.  original form.
  54.   If you DO modify or enhance any of this code, please send any such changes
  55.  to me for incorporation into a future version.  Any such enhancements will
  56.  be DONATED, without expectation of compensation or incorporation into
  57.  future versions.  Again, if you distribute this code, please do so in its
  58.  original, unmodified form including all source files and documentation.
  59.  
  60. Source files included
  61. =====================
  62.  TDE     .DOC: This documentation.
  63.  TDE     .MAN: How to use TDataEntry in your dialog objects
  64.  TDE     .H  : header file containing class declarations for classes
  65.  TDEFLAGS.H  :   "     "      "       flags and command definitions
  66.  TDE     .CPP: Class TDataEntry
  67.  TDEDATE .CPP: Class TDEDate
  68.  TDEPHONE.CPP: Classes TDEPhone, TDEZipCode, TDEState
  69.  TDENUMS .CPP: Class TDEInteger
  70.  TDECLUST.CPP: Non-TDataEntry classes TDEButton, TDERadioButtons, TDECheckBoxes
  71.  TDEINPLI.CPP: Non-TDataEntry class TDEInputLine
  72.  TDELIB  .PRJ: Project for building library TDELIB.LIB
  73.  TDEDEMO .CPP: Demo program
  74.  TDEDEMO .PRJ: Project for building TDEDEMO.EXE
  75.  
  76. What's Missing?
  77. ===============
  78.   I haven't yet made TDataEntry streamable, nor has data formatting been
  79.  incorporated.  I'm sure other stuff is missing -- please let me know.
  80.   The source provided is lacking most of the development comments, etc.
  81.  During development, all changes/corrections were meticulously documented and
  82.  this added up to voluminous comments which would only clutter the source and
  83.  increase download time.  Therefore, you must be especially careful when
  84.  tinkering with the code.  If you have any questions, please post a message
  85.  to me.
  86.  
  87. Class TDataEntry Summary of Class Members: TDE.H, TDE.CPP
  88. =========================================================
  89.  
  90. public:
  91. **
  92.   MASK_CHAR:
  93.     The default mask character, '~'.  Within a mask, this character indicates
  94.     that data may be entered in that position.  Currently their is no
  95.     method for including MASK_CHAR literally within a mask.
  96. **
  97.   uchar  localMode:
  98.     The mode characteristics specific to a particular instance, which is a
  99.     combination of OR'd tdlXXXXXXX flags defined in TDEFLAGS.H.
  100. **
  101.   ushort dataFormat:
  102.     The dataFormat flags for a particular instance, NOT YET IMPLEMENTED.
  103. **
  104.   static uchar  globalID:
  105.     The global field number counter.  This should be initialized to zero
  106.     at the beginning of creation of each dialog containing TDataEntry
  107.     objects.  TDataEntry objects will then be numbered consecutively from
  108.     1 - 255 which will allow them to be located via a call to
  109.     TDataEntry::locateID.
  110. **
  111.   static ushort globalMode
  112.     The global mode characteristics which affect ALL instances of TDataEntry
  113.     objects, which is a combination of OR'd tdgXXXXXX flags defined in
  114.     TDEFLAGS.H.
  115. **
  116.   static char *msgDataRequired:
  117.     The default message to be displayed when a required field is not filled
  118.     in.  This is used if the field uses the default validData() function, or
  119.     does not define its own message in its validData() function.
  120.     Default definition:
  121.       char  *TDataEntry::msgDataRequired = "\003Required data is missing!";
  122. **
  123.   static char *msgDataInvalid
  124.     Same as msgDataRequired, except for the case when data is invalid.
  125.     Default definition:
  126.       char  *TDataEntry::msgDataInvalid  = "\003Invalid data!";
  127. **
  128.   static char secureChar:
  129.     The default secure character.  If the fields localMode includes the
  130.     tdlSecure mask, then all input is displayed using this character.  To
  131.     be used for password fields, etc.  Default definition:
  132.       char   TDataEntry::secureChar = '#';
  133. **
  134.   CONSTRUCTOR 1:
  135.   -------------
  136.   TDataEntry(int col, int row, char *format, const char *fName = NULL ):
  137.     Creates a TDataEntry object at 'col', 'row' within its owner, using a
  138.     format mask defined 'format'.  Its length will be the length of 'format',
  139.     and it will be assigned a field name of 'fName' if non-NULL.  The actual
  140.     length of its data member (inherited from TInputLine) will be the length
  141.     of 'format' minus the total number of non-MASK characters in 'format'.
  142. **
  143.   CONSTRUCTOR 2:
  144.   -------------
  145.   TDataEntry(int col, int row, int len, const char *fName = NULL ):
  146.     Creates a TDataEntry object at 'col', 'row' within its owner, of length
  147.     'len'.  This constructor is used when ALL positions are writable and is
  148.     equivalent to calling CONSTRUCTOR 1 with a format = 'len' MASK char's.
  149. **
  150.   DESTRUCTOR:
  151.   ----------
  152.   ~TDataEntry():
  153.     Cleans up the heap.  (Some data is inherited from TInputLine, which is
  154.     why the destructor does not destroy these members.)
  155. **
  156.   void selectAll( Boolean enable ):
  157.     A TDataEntry-specific version of TInputLine's selectAll().  Since
  158.     selectAll() is NOT virtual in TInputLine, you have to be careful when
  159.     other classes  call selectAll() (such as THistory).  In these cases,
  160.     TInputLine's selectAll() will be called with undesirable results.  A
  161.     solution for THistory is documented in TDE.MAN.
  162. **
  163.   virtual ushort dataSize():
  164.   virtual void getData( void *rec ):
  165.   virtual void setData( void *rec ):
  166.   virtual Boolean valid(ushort):
  167.     These are all fairly standard deviations/derivations of standard TV
  168.     functions.  Some must be overridden in derived classes.
  169. **
  170.   virtual void draw():
  171.   virtual void handleEvent(TEvent& event):
  172.   virtual void setState( ushort aState, Boolean enable ):
  173.     These are TDataEntry-specific versions which probably should not be
  174.     tampered with.
  175. **
  176.   virtual Boolean validData( const char *InvalidMsg, char const *RequiredMsg ):
  177.     The default validData() calls the validKey() function to double check
  178.     valid input.  Override in derived classes for more detailed checking
  179.     of validity.
  180. **
  181.   virtual Boolean validKey(uchar *key ) { return (Boolean)isprint(*key); }:
  182.     The default validKey() accepts any printable character.  Override in
  183.     derived classes for different behavior (eg, numbers only).
  184. **
  185.   static  inline  TDataEntry *locateID( TView *fieldOwner, uchar fieldNumber,
  186.                                         Boolean select = False ):
  187.     This function sends a broadcast message with command 'cmTDGotoNumber' to
  188.     'fieldOwner', which a TDataEntry object with localID member = fieldNumber
  189.     will respond to.  If 'select' is True, the field will be selected,
  190.     otherwise it won't.  Returns a pointer to the field, NULL if not found.
  191. **
  192.   static  inline  TDataEntry *locateName( TView *fieldOwner, const char *fName,
  193.                                           Boolean select = False ):
  194.     This function sends a broadcast message with command 'cmTDGotoName' to
  195.     'fieldOwner', which a TDataEntry object with fieldName member = fName
  196.     will respond to.  If 'select' is True, the field will be selected,
  197.     otherwise it won't.  Returns a pointer to the field, NULL if not found.
  198. **
  199.   static  inline void resetData( TView *fieldOwner, TDataEntry *target = NULL):
  200.     This function sends a broadcast message with command 'cmTDResetData' to
  201.     'fieldOwner'.  If 'target' != NULL, then only 'target' (if found) will reset
  202.     its data.  Otherwise, ALL of fieldOwner's TDataEntry objects will reset
  203.     their data.  Resetting data copies the contents of the field's 'data'
  204.     member into its 'origData' member.  After a call to resetData, calls to
  205.     TDataEntry::queryChanged() will return False until data is once again
  206.     modified.  This is useful when you save the contents of a dialog to
  207.     disk but want the dialog to remain displayed.  Resetting the data after
  208.     the save will prevent you from re-saving the data if it hasn't been
  209.     further modified.
  210. **
  211.   static  inline TDataEntry *queryChanged( TView *fieldOwner, TDataEntry *target = NULL):
  212.     This function sends a broadcast message with command 'cmTDQueryChanged' to
  213.     'fieldOwner'.  If 'target' != NULL, then only 'target' MIGHT respond,
  214.     otherwise ALL of fieldOwner's TDataEntry objects will receive the message.
  215.     This function returns a pointer to the FIRST field which responds in the
  216.     affirmative, NULL if no data has been changed or, if 'target' is specified,
  217.     if 'target' isn't found.
  218. **
  219.   static  inline  TDataEntry *queryValid( TView *fieldOwner, TDataEntry *target = NULL):
  220.     This functions sends a broadcast message with command 'cmTDQueryValid' to
  221.     'fieldOwner'.  If 'target' != NULL, then only 'target' MIGHT respond,
  222.     otherwise ALL of fieldOwner's TDataEntry objects will receive the message.
  223.     The function returns a pointer to the FIRST field which contains invalid
  224.     data, NULL if all data is valid or, if 'target' is specified, if 'target'
  225.     isn't found.
  226.  
  227. protected:
  228. **
  229.   char  *mask:
  230.     This member contains a copy of the 'format' argument passed by
  231.     CONSTRUCTOR 1, or one created by CONSTRUCTOR 2.
  232. **
  233.   char  *outView:
  234.     This member contains a picture of the field as viewed on the screen.
  235. **
  236.   char  *origData:
  237.     This member contains a copy of 'data' as set by setData() and is used
  238.     when querying if field contents have changed.
  239. **
  240.   int   tdCurPos:
  241.   int   tdLastPos:
  242.   int   tdSelStart:
  243.   int   tdSelEnd:
  244.     These members are used internally to keep track of current positions
  245.     within outView and mask.  They should NOT be tampered with.
  246. **
  247.   ushort  localID:
  248.     This contains the field number for the object.  If you initialize
  249.     TDataEntry::globalID to 0 at the beginning of creation of a dialog box,
  250.     then all TDataEntry objects within the box will be assigned localID's
  251.     within the range 1 - 255.  Once TDataEntry::globalID hits 255, all
  252.     objects created will then be numbered with 255.  You can use localID to
  253.     locate a field by number.
  254. **
  255.   char    *fieldName:
  256.     If 'fName' is passed to the constructor, then fieldName will contain
  257.     'fName'.  You can then locate the field by name.
  258.  
  259. private:
  260. **
  261.   int  mousePos( TEvent& event ):
  262.   void deleteSelect():
  263.   void near setViewPos(ushort):
  264.   void near formatView():
  265.     None of these should be messed with.
  266.  
  267. INHERITED FROM TInputLine:
  268. -------------------------
  269. public:
  270. **
  271.   char  *data:
  272.     Contains the raw field data.  TDataEntry's CONSTRUCTOR 1 deletes this
  273.     and allocates a new one of a length less the number of non-MASK char's.
  274. **
  275.   int   maxLen:
  276.     Contains the maximum data length.  TDataEntry's constructors may alter
  277.     this value.
  278. **
  279.   int   curPos:
  280.   int   firstPos:
  281.   int   selStart:
  282.   int   selEnd:
  283.     These members are used pretty much as they are in TInputLine.  They
  284.     keep track of positions within the 'data' member, as compared to their
  285.     tdXXXX counterparts, which track position with the mask and outView.
  286.  
  287.  
  288. TDataEntry flags and commands: TDEFLAGS.H
  289. =========================================
  290.  
  291. Global control flags
  292. --------------------
  293.  These flags are used to set TDataEntry's static globalMode data member.  ALL
  294. TDataEntry objects are affected by these flags.  You set globalMode by
  295. logically OR'ing the flags.  By default, TDataEntry::globalMode is defined
  296. as follows:
  297.   ushort TDataEntry::globalMode = (tdgBeepEnable | tdgSelectOnFocus);
  298.  
  299.   * tdgEnterIsTab
  300.      This flag makes the ENTER/RETURN key behave like the TAB key.  By default,
  301.     ENTER pushes the default button, usually resulting in exit from the
  302.     dialog.  Using this flag allows inter-field movement via the ENTER key.
  303.  
  304.   * tdgBeepEnable
  305.      This flag enables sound for validation error, etc. (on by default)
  306.  
  307.   * tdgUpDownEnable
  308.      This flag makes the UP/DOWN arrow keys behave like TAB/SHIFT-TAB, allowing
  309.     UP/DOWN to be used for inter-field movement.
  310.  
  311.   * tdgValidNow
  312.      This flag enables immediate validation when exiting a field via TAB,
  313.     SHIFT-TAB, ENTER (if enabled), or arrow keys (if enabled; see below).
  314.     If you don't choose immediate validation, you can call
  315.     TDataEntry::queryValid() before exiting the dialog.  Currently, field
  316.     validation is NOT perform when a field is exited via mouse movement.
  317.     Therefore, TDataEntry::queryValid() should ALWAYS be called prior to
  318.     saving data or whatever it is you want to do with the data.
  319.  
  320.   * tdgValidUpDown
  321.      This flag enables immediate validation when UP/DOWN arrow movement causes
  322.     exit from a field.  It only works if the tdgValidNow and tdgUpDownEnable
  323.     are enabled.
  324.  
  325.   * tdgSelectOnFocus
  326.      If enabled (the default), then a field's contents are selected when
  327.     the field recieves focus (like TInputLine).  I've run into users who get
  328.     extremely angry when the first keystroke deletes the field contents so
  329.     its nice to let the user be able to toggle this.
  330.  
  331.   * tdgReserved_2
  332.   * tdgReserved_3
  333.   * tdgReserved_4
  334.   * tdgReserved_5
  335.      Unused.
  336.  
  337. Local control flags
  338. -------------------
  339.  These flags are used to set each field's localMode data member, allowing each
  340. field to behave differently depending on its unique requirements.  By
  341. default, each object's localMode is set as follows:
  342.   localMode = tdlRLArrows | tdlInsertEnable;
  343.  
  344.   * tdlAutoExit
  345.      If enabled, the field exits automatically when a valid character is
  346.     typed in the last field position.  Handy for dates, phone numbers, etc.
  347.  
  348.   * tdlRightToLeft
  349.      Unused.  Originally intended for a TDataEntry object which employs
  350.     right-to-left calculator-style field movement.  That project's on hold
  351.     right now.  I think TDataEntry is big enough and that a right-to-left
  352.     implementation will need to be a completely separate object.
  353.  
  354.   * tdlRLArrows
  355.      Unused.  Originally intended to be used in a right-to-left object as
  356.     described above.
  357.  
  358.   * tdlInsertEnable
  359.      Enables the insert toggle (on by default).
  360.  
  361.   * tdlRequired
  362.      This flag informs the field's validData() that the data is required;
  363.     validation will fail if this flag is set and the field is left blank.
  364.  
  365.   * tdlSecure
  366.      If set, then all valid characters will be displayed using the
  367.     static TDataEntry::secureChar (default = '#').  Useful for passwords or
  368.     other 'secret' data.
  369.  
  370. Format control flags - sets dataFormat - local to each TDE object
  371. -----------------------------------------------------------------
  372.  Data formatting is not yet implemented, so these flags are currently
  373. unused but are documented with their intended purpose.
  374.  
  375.   * tdfUpper
  376.      If set, data is converted to uppercase.
  377.   * tdfLower
  378.      If set, data is converted to lowercase.
  379.   * tdfRightJust
  380.      If set, data is right-justified, padded on left with spaces up to maxLen.
  381.   * tdfLeftJust
  382.      If set, data is left-justified, padded on right with spaces up to maxLen.
  383.   * tdfCenter
  384.      If set, data is centered, padded on right/left with spaces up to maxLen.
  385.  
  386. TDataEntry commands
  387. -------------------
  388.   These commands are used by the static query functions.  They may be used
  389. directly in the message() function if you study their use in the query
  390. functions.  If they conflict with any command constants which you've defined,
  391. you'll need to change them.  The following documents which function uses the
  392. command; refer to the function description above for a description of the
  393. function's behavior.
  394.  
  395.   * cmTDQueryValid       41456u
  396.      Used by TDataEntry::queryValid().
  397.  
  398.   * cmTDQueryValidQuiet  41457u
  399.      Unused.  Intended to behave like cmTDQueryValid except to do so quietly.
  400.  
  401.   * cmTDQueryChanged     41458u
  402.      Used by TDataEntry::queryChanged().
  403.  
  404.   * cmTDGotoNumber       48459u
  405.      Used by TDataEntry::locateID().
  406.  
  407.   * cmTDGotoName         48560u
  408.      Used by TDataEntry::locateName().
  409.  
  410.   * cmTDResetData        48561u
  411.      Used by TDataEntry::resetData().  See description of this function above.
  412.  
  413. Sample derived classes included
  414. ================================
  415.  
  416.   class TDEAlpha - alpha strings only  ( TDE.H )
  417.   ----------------------------------------------
  418.   This class allows only alphabetic data to be entered.  Data type is string.
  419.  
  420.   class TDEAlphaNum - alphanumeric strings only  ( TDE.H )
  421.   --------------------------------------------------------
  422.   This class allows only alphanumeric data to be entered. Data type is string.
  423.  
  424.   class TDENumeric - numeric strings only  ( TDE.CPP )
  425.   ----------------------------------------------------
  426.   This class allows only numeric data to be entered.  If its SpaceAllowed data
  427.   member is True, data may contain numbers AND spaces, otherwise spaces will
  428.   not be allowed.  Data type is string.
  429.  
  430.   class TDEInteger - signed integer values ( TDENUMS.CPP )
  431.   --------------------------------------------------------
  432.   This class allows only signed integer data to be entered (it currently
  433.   doesn't accept the minus sign, however...that was overlooked.  So, in effect,
  434.   it only accepts unsigned integers but stores them as signed int).  Data type
  435.   is integer.
  436.  
  437.   class TDEDate - date strings only (TDEDATE.CPP)
  438.   -----------------------------------------------
  439.   This class allows dates of the form xx/xx/xx or xx/xx/xxxx to be entered.
  440.   Data type is unsigned long.  Static members control default century and format:
  441.   TDEDate::defCentury = 19 by default.  defCentury is used in fields of the
  442.     form xx/xx/xx, where century is not input but is assumed.
  443.   TDEDate::defFormat  = dateMDY.  This field controls the order in which
  444.     month, day, and year are entered.  See the #defines in the source.
  445.  
  446.   class TDEPhone - phone number strings only (TDEPHONE.CPP)
  447.   ---------------------------------------------------------
  448.   Accepts phone numbers in the form (xxx) xxx-xxx.  Data type is string.
  449.  
  450.   class TDEZipCode - zip code strings only (TDEPHONE.CPP)
  451.   -------------------------------------------------------
  452.   Accepts zip codes in the form xxxxx or xxxxx-xxxx.  Data type is string.
  453.  
  454.   class TDEState - state abbreviation strings only (TDEPHONE.CPP)
  455.   ---------------------------------------------------------------
  456.   Accepts two digit state codes and capitalizes them.  Data type is string.
  457.  
  458.   class TDEButton ( TDECLUST.CPP )
  459.   --------------------------------
  460.   This is a non-TDataEntry TButton derivative which is designed to handle
  461.   arrow-key movement consistent with the behavior of TDataEntry objects.
  462.  
  463.   class TDEInputLine  ( TDEINPLI.CPP )
  464.   ------------------------------------
  465.   This is a non-TDataENtry TInputLine derivative which is designed to handle
  466.   enter/arrow-key movement consistent with the behavior of TDataEntry objects.
  467.   In addition, it responds to CTRL-R and the TDataEntry query functions.
  468.  
  469.   class TDERadioButtons  ( TDECLUST.CPP )
  470.   ---------------------------------------
  471.   This is a non-TDataEntry TRadioButtons derivative which is designed to
  472.   handle enter key movement consistent with the behavior of TDataEntry
  473.   objects.  In addition, it responds to the TDataEntry query functions.  (It's
  474.   easy for the user to 'restore' button data, so CTRL-R logic is omitted.)
  475.   Up/down arrow movement is not modified.
  476.  
  477.   class TDECheckBoxes  ( TDECLUST.CPP )
  478.   -------------------------------------
  479.   This is a non-TDataEntry TCheckBoxes derivative which is designed to
  480.   handle enter key movement consistent with the behavior of TDataEntry
  481.   objects.  In addition, it responds to the TDataEntry query functions.  (It's
  482.   easy for the user to 'restore' button data, so CTRL-R logic is omitted.)
  483.   Up/down arrow movement is not modified.
  484.  
  485.   //******************** TDE.DOC ends ***************************//